#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <ctype.h>
#include <signal.h>
#include <pthread.h>

//1 mcu

// 串口配置结构体
typedef struct {
    char* name;         // 设备名称
    int fd;             // 文件描述符
    int baud_rate;      // 波特率
    int data_bits;      // 数据位
    int stop_bits;      // 停止位
    char parity;        // 校验位
} Uart_t;

Uart_t* g_uart_mcu = nullptr;          // 串口上下文指针
pthread_mutex_t mcu_data_lock = PTHREAD_MUTEX_INITIALIZER;  //静态锁，针对串口mcu的串口；读数据保护，写数据保护

//2 laser
Uart_t* g_uart_laser = nullptr;          // 串口上下文指针
//3 红外
Uart_t* g_uart_icr = nullptr;          // 串口上下文指针
//4 可见
Uart_t* g_uart_vis = nullptr;          // 串口上下文指针
//5 镜头
Uart_t* g_uart_lens = nullptr;          // 串口上下文指针
//6 RS422传输数据口
Uart_t* g_uart_usb0 = nullptr;          // 串口上下文指针
pthread_mutex_t usb0_data_lock = PTHREAD_MUTEX_INITIALIZER;  //静态锁，针对串口usb0的串口；读数据保护，写数据保护

pthread_mutex_t select_video_lock = PTHREAD_MUTEX_INITIALIZER;  //静态锁，针对串口usb0的串口；读数据保护，写数据保护
// 全局变量：循环发送标志
volatile int keep_running = 1;

// 信号处理函数：用于处理Ctrl+C中断
void signal_handler(int sig) {
    if (sig == SIGINT) {
        printf("\n接收到中断信号，停止发送\n");
        keep_running = 0;
    }
}

// 初始化串口上下文
Uart_t* uart_init_context(const char* name) {
    Uart_t* ctx = (Uart_t*)malloc(sizeof(Uart_t));
    if (!ctx) {
        perror("内存分配失败");
        return NULL;
    }
    memset(ctx, 0, sizeof(Uart_t));
    
    ctx->name = strdup(name);
    if (!ctx->name) {
        free(ctx);
        perror("字符串复制失败");
        return NULL;
    }
    
    ctx->fd = -1;
    // 固定串口参数，可根据需要修改
    ctx->baud_rate = 4000000;  // 波特率设置为4000000
    ctx->data_bits = 8;        // 数据位
    ctx->stop_bits = 1;        // 停止位
    ctx->parity = 'N';         // 校验位 (N:无, O:奇, E:偶)
    
    return ctx;
}

// 释放串口上下文
void uart_free_context(Uart_t* ctx) {
    if (ctx) {
        if (ctx->name) {
            free(ctx->name);
        }
        if (ctx->fd >= 0) {
            close(ctx->fd);
        }
        free(ctx);
    }
}

// 打开并配置串口
int open_and_configure_uart(Uart_t* ctx) {
    if (!ctx) {
        perror("上下文为空");
        return -1;
    }
    
    // 打开串口设备
    ctx->fd = open(ctx->name, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (ctx->fd < 0) {
        printf("打开串口 %s 失败: %s\n", ctx->name, strerror(errno));
        return -1;
    }
    
    // 配置串口参数
    struct termios options;
    if (tcgetattr(ctx->fd, &options) != 0) {
        perror("获取串口属性失败");
        close(ctx->fd);
        ctx->fd = -1;
        return -1;
    }
    
    // 清除数据位掩码
    options.c_cflag &= ~CSIZE;
    
    // 设置输入模式（原始模式）
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    
    // 设置输出模式
    options.c_oflag &= ~OPOST;
    
    // 禁用软件流控制
    options.c_iflag &= ~(IXON | IXOFF | IXANY);
    
    // 设置波特率（重点修改：添加4000000波特率支持）
    switch (ctx->baud_rate) {
        case 9600:    cfsetispeed(&options, B9600);   cfsetospeed(&options, B9600);   break;
        case 19200:   cfsetispeed(&options, B19200);  cfsetospeed(&options, B19200);  break;
        case 38400:   cfsetispeed(&options, B38400);  cfsetospeed(&options, B38400);  break;
        case 115200:  cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); break;
        case 1000000: cfsetispeed(&options, B1000000);cfsetospeed(&options, B1000000);break;
        case 2000000: cfsetispeed(&options, B2000000);cfsetospeed(&options, B2000000);break;
        case 3000000: cfsetispeed(&options, B3000000);cfsetospeed(&options, B3000000);break;
        case 4000000: cfsetispeed(&options, B4000000);cfsetospeed(&options, B4000000);break; // 添加4000000波特率
        default:      
            cfsetispeed(&options, B115200); 
            cfsetospeed(&options, B115200);
            printf("使用默认波特率 115200\n");
    }
    
    // 设置校验位
    switch (ctx->parity) {
        case 'O':  // 奇校验
            options.c_cflag |= PARENB | PARODD;
            break;
        case 'E':  // 偶校验
            options.c_cflag |= PARENB;
            options.c_cflag &= ~PARODD;
            break;
        case 'N':  // 无校验
        default:
            options.c_cflag &= ~PARENB;
    }
    
    // 设置数据位
    switch (ctx->data_bits) {
        case 7: options.c_cflag |= CS7; break;
        case 8: default: options.c_cflag |= CS8; break;
    }
    
    // 设置停止位
    switch (ctx->stop_bits) {
        case 2: options.c_cflag |= CSTOPB; break;
        case 1: default: options.c_cflag &= ~CSTOPB; break;
    }
    
    // 启用接收和本地模式
    options.c_cflag |= CLOCAL | CREAD;
    
    // 设置超时和最小接收字符数
    options.c_cc[VTIME] = 5;  // 0.5秒超时
    options.c_cc[VMIN] = 0;   // 不等待字符
    
    // 应用配置
    if (tcsetattr(ctx->fd, TCSANOW, &options) < 0) {
        perror("设置串口属性失败");
        close(ctx->fd);
        ctx->fd = -1;
        return -1;
    }
    
    printf("串口配置成功：%s\n", ctx->name);
    printf("参数：波特率=%d, 数据位=%d, 停止位=%d, 校验=%c\n",
           ctx->baud_rate, ctx->data_bits, ctx->stop_bits, ctx->parity);
    return 0;
}

// 向串口发送数据
int send_data(Uart_t* ctx, unsigned char* data, int len) {
    if (!ctx || ctx->fd < 0 || !data || len <= 0) {
        return -1;
    }
    
    int ret = write(ctx->fd, data, len);
    if (ret != len) {
        printf("发送失败，预期发送 %d 字节，实际发送 %d 字节\n", len, ret);
        return -1;
    }
    return 0;
}

int main() {
    // 配置串口设备，根据实际情况修改
    const char* uart_device = "/dev/ttyUSB0";  // 串口设备路径，根据实际情况修改
    
    // 初始化串口上下文
    Uart_t* uart = uart_init_context(uart_device);
    if (!uart) {
        return 1;
    }
    
    // 打开并配置串口
    if (open_and_configure_uart(uart) < 0) {
        uart_free_context(uart);
        return 1;
    }
    
    // 设置信号处理函数，用于处理Ctrl+C
    signal(SIGINT, signal_handler);
    printf("开始从0到10000循环发送数据...\n");
    printf("按Ctrl+C停止发送\n");
    
    // 循环发送0到10000的数据
    int count = 0;
    char send_buf[32];  // 缓冲区用于存储转换后的字符串
    while (keep_running) {
        // 将数字转换为字符串，格式如"1234\n"（带换行符，方便接收端解析）
        int len = snprintf(send_buf, sizeof(send_buf), "%d\n", count);
        
        // 发送数据
        if (send_data(uart, (unsigned char*)send_buf, len) < 0) {
            printf("数据发送失败\n");
            break;
        } else {
            // 每100个数据打印一次状态，避免输出过多
            if (count % 100 == 0) {
                printf("已发送: %d\n", count);
            }
        }
        
        // 递增计数，到达10000后重置为0
        count++;
        if (count > 10000) {
            count = 0;
        }
        
        // 延时控制发送速率（4000000波特率下可适当减小延时）
        usleep(1000);  // 1ms，约1000Hz发送频率（可根据需要调整）
    }
    
    // 释放资源
    uart_free_context(uart);
    printf("程序结束\n");
    
    return 0;
}